import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Role, RoleDocument } from './schemas/role.schema';
import { CreateRoleDto } from './dto/create-role.dto';
import { UpdateRoleDto } from './dto/update-role.dto';
import { UsersService } from '../users/users.service';

@Injectable()
export class RolesService {
  constructor(
    @InjectModel(Role.name) private roleModel: Model<RoleDocument>,
    private usersService: UsersService,
  ) {}
  
  async create(createRoleDto: CreateRoleDto): Promise<Role> {
    // 检查同名角色是否存在
    const existingRole = await this.roleModel.findOne({ 
      name: createRoleDto.name,
      orgId: createRoleDto.orgId,
    }).exec();
    
    if (existingRole) {
      throw new BadRequestException('角色名称在该组织中已存在');
    }
    
    const createdRole = new this.roleModel(createRoleDto);
    return createdRole.save();
  }
  
  async findAll(orgId?: string): Promise<Role[]> {
    if (orgId) {
      return this.roleModel.find({ orgId }).exec();
    }
    return this.roleModel.find().exec();
  }
  
  async findOne(id: string): Promise<Role> {
    const role = await this.roleModel.findById(id)
      .populate('permissionIds')
      .exec();
      
    if (!role) {
      throw new NotFoundException(`角色 ID ${id} 不存在`);
    }
    
    return role;
  }
  
  async update(id: string, updateRoleDto: UpdateRoleDto): Promise<Role> {
    // 如果更新名称，检查是否存在同名角色
    if (updateRoleDto.name) {
      const existingRole = await this.roleModel.findOne({
        name: updateRoleDto.name,
        orgId: updateRoleDto.orgId,
        _id: { $ne: id }
      }).exec();
      
      if (existingRole) {
        throw new BadRequestException('角色名称在该组织中已存在');
      }
    }
    
    const updatedRole = await this.roleModel.findByIdAndUpdate(
      id, 
      updateRoleDto, 
      { new: true }
    ).exec();
    
    if (!updatedRole) {
      throw new NotFoundException(`角色 ID ${id} 不存在`);
    }
    
    return updatedRole;
  }
  
  async remove(id: string): Promise<void> {
    const role = await this.roleModel.findById(id).exec();
    
    if (!role) {
      throw new NotFoundException(`角色 ID ${id} 不存在`);
    }
    
    // 删除角色前，从所有用户中移除此角色引用
    await this.usersService.removeRoleFromUsers(id);
    
    await this.roleModel.findByIdAndDelete(id).exec();
  }
  
  // 批量删除角色
  async removeMany(ids: string[]): Promise<void> {
    await this.roleModel.deleteMany({ _id: { $in: ids } }).exec();
  }
  
  // 为角色分配权限
  async assignPermissions(roleId: string, permissionIds: string[]): Promise<Role> {
    const updatedRole = await this.roleModel.findByIdAndUpdate(
      roleId,
      { permissionIds },
      { new: true }
    ).exec();
    
    if (!updatedRole) {
      throw new NotFoundException(`角色 ID ${roleId} 不存在`);
    }
    
    return updatedRole;
  }
  
  // 从所有角色的 permissionIds 中移除指定权限
  async removePermissionFromRoles(permissionId: string): Promise<void> {
    await this.roleModel.updateMany(
      { permissionIds: permissionId },
      { $pull: { permissionIds: permissionId } }
    ).exec();
  }
  
  // 检查机构下是否有角色
  async hasRolesByOrgId(orgId: string): Promise<boolean> {
    const count = await this.roleModel.countDocuments({ orgId }).exec();
    return count > 0;
  }
  
  // 获取机构下的所有角色
  async findRolesByOrgId(orgId: string): Promise<Role[]> {
    return this.roleModel.find({ orgId }).exec();
  }
} 